﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using CodeStash.Common.DTOS;
using System.Configuration;
using System.Reflection;
using System.Threading;
using CodeStash.Common.Enums;

namespace CodeStash.Addin.Core
{
    /// <summary>
    /// All addin operations will inherit from this class. This is based entirely on Sacha's test cases.
    /// </summary>
    [Serializable]
    public abstract class CodeStashRestBase
    {

        #region Members
        internal static NameValueCollection values = new NameValueCollection();

        protected LoginDetails loginDetails;
        protected static string emailAddress;
        protected static string password;
        protected static string openId;
        #endregion

        /// <summary>
        /// Instantiate a new instance of <see cref="CodeStashRestBase"/>.
        /// </summary>
        public CodeStashRestBase()
        {
        }

        public void SetLoginDetails(LoginDetails login)
        {
            if (login == null) return;
            loginDetails = login;
            SetLoginDetails();
        }

        protected byte[] GetCategoryFromSnippetService(string category)
        {
            return CallService(category, CodeStash.Common.Helpers.ConfigurationSettings.CodeSnippetAddress, "TryFindCategory");
        }



        protected byte[] Search(string searchText, SearchType searchType, CodeSnippetVisibility visibility,
            string[] tags, int pageSize, int pageNumber, bool includeRatings, int rating)
        {
            JSONSearchInput input = new JSONSearchInput(
                openId, // If not specified, will be an empty string but the password must be set.
                emailAddress, // Must always be present.
                password, // If not specified, will be an empty string, but the OpenID must be set.
                searchType,
                searchText,
                pageNumber,
                pageSize,
                visibility,
                tags,
                includeRatings,
                rating
                );

            return CallService(input, CodeStash.Common.Helpers.ConfigurationSettings.RestAddress, "Search");

        }

        protected byte[] GetDataFromRestService(LoginDetails loginDetails)
        {
            JSONCredentialInput input = new JSONCredentialInput(
                loginDetails.Token.GetStringForWebsiteCall(), // If not specified, will be an empty string but the password must be set.
                loginDetails.EmailAddress.GetStringForWebsiteCall(), // Must always be present.
                loginDetails.Password.GetStringForWebsiteCall() // If not specified, will be an empty string, but the OpenID must be set.
                );
            return CallService(input, CodeStash.Common.Helpers.ConfigurationSettings.RestAddress, "GetAllLanguages");
        }

        protected byte[] GetDataFromRestService(string restMethod)
        {
            JSONCredentialInput input = new JSONCredentialInput(
                openId, // If not specified, will be an empty string but the password must be set.
                emailAddress, // Must always be present.
                password // If not specified, will be an empty string, but the OpenID must be set.
                );
            return CallService(input, CodeStash.Common.Helpers.ConfigurationSettings.RestAddress, restMethod);
        }

        protected byte[] GetDataFromRestService(JSONCodeSnippet snippet)
        {
            JSONAddSnippetInput input = new JSONAddSnippetInput(
                openId, // If not specified, will be an empty string but the password must be set.
                emailAddress, // Must always be present.
                password, // If not specified, will be an empty string, but the OpenID must be set.
                snippet,
                true //specifies snippet is pre Html encoded
                );

            return CallService(input, CodeStash.Common.Helpers.ConfigurationSettings.RestAddress, "AddSnippet");
        }

        private byte[] CallService<T>(T input, string address, string methodToCall)
        {
            values = new NameValueCollection();
            Utilities.AddValue(values, "input", input);

            WebClient client = new WebClient();
            return client.UploadValues(string.Format("{0}{1}", address, methodToCall), values);
        }

        /// <summary>
        /// Get the login details of this user from the isolated storage.
        /// </summary>
        private void SetLoginDetails()
        {
            if (loginDetails == null) return;

            emailAddress = loginDetails.EmailAddress.GetStringForWebsiteCall();
            password = loginDetails.Password.GetStringForWebsiteCall();
            openId = loginDetails.Token.GetStringForWebsiteCall();
        }

    }
}